package cn.java.threadmodel.producerconsumer.waitnotify;

import java.util.LinkedList;
import java.util.Queue;
/**
 * @author 小石潭记
 * @date 2021/12/18 9:58
 * @Description: wait/notify机制实现生产者-消费者模型
 */
public class ProducerConsumerQueue<E> {
    /**
     * 队列最大容量
     */
    private final static int QUEUE_MAX_SIZE = 3;
    /**
     * 存放元素的队列
     */
    private Queue<E> queue;

    public ProducerConsumerQueue() {
        queue = new LinkedList<>();
    }

    /**
     * 向队列中添加元素
     *
     * @param e
     * @return
     */
    public synchronized boolean put(E e) {
        // 如果队列是已满，则阻塞当前线程
        while (queue.size() == QUEUE_MAX_SIZE) {
            try {
                wait();
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
        // 队列未满，放入元素，并且通知消费线程
        queue.offer(e);
        System.out.println(Thread.currentThread().getName() + " -> 生产元素，元素个数为：" + queue.size());
        notify();
        return true;
    }

    /**
     * 从队列中获取元素
     * @return
     */
    public synchronized E get() {
        // 如果队列是空的，则阻塞当前线程
        while (queue.isEmpty()) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        // 队列非空，取出元素，并通知生产者线程
        E e = queue.poll();
        System.out.println(Thread.currentThread().getName() + " -> 消费元素，元素个数为：" + queue.size());
        notify();
        return e;
    }
}

